package com.kaibes.orm.spring;

import java.util.Map;
import java.util.function.Function;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import com.kaibes.orm.core.core.TableService;
import com.kaibes.orm.core.listener.MapCacheListener;

@Component
public class OrmUtils implements ApplicationContextAware {

    private ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    public void openMapperCache(Function<Object, String> keyFunction, Class<?>... clazzs) {
        if (clazzs.length == 0) {
            Map<String, Object> serviceMap = applicationContext.getBeansWithAnnotation(Service.class);
            serviceMap.forEach((t, u) -> {
                if (u instanceof TableService) {
                    TableService<?> service = (TableService<?>) u;
                    if (service.getMapper().getCacheListener() == null) {
                        service.getMapper().setCacheListener(new MapCacheListener<>(keyFunction));
                    }
                }
            });
        } else {
            for (Class<?> clazz : clazzs) {
                TableService<?> service = (TableService<?>) applicationContext.getBean(clazz);
                if (service.getMapper().getCacheListener() == null) {
                    service.getMapper().setCacheListener(new MapCacheListener<>(keyFunction));
                }
            }
        }
    }

    public void openMapperCacheIgnore(Function<Object, String> keyFunction, Class<?>... clazzs) {
        if (clazzs.length == 0) {
            Map<String, Object> serviceMap = applicationContext.getBeansWithAnnotation(Service.class);
            serviceMap.forEach((t, u) -> {
                if (u instanceof TableService) {
                    TableService<?> service = (TableService<?>) u;
                    if (service.getMapper().getCacheListener() == null) {
                        service.getMapper().setCacheListener(new MapCacheListener<>(keyFunction));
                    }
                }
            });
        } else {
            Map<String, Object> serviceMap = applicationContext.getBeansWithAnnotation(Service.class);
            serviceMap.forEach((t, u) -> {
                if (u instanceof TableService) {
                    for (Class<?> class1 : clazzs) {
                        if (u.getClass() == class1) {
                            return;
                        }
                    }

                    TableService<?> service = (TableService<?>) u;
                    if (service.getMapper().getCacheListener() == null) {
                        service.getMapper().setCacheListener(new MapCacheListener<>(keyFunction));
                    }
                }
            });
        }
    }

}
